package com.jzo2o.foundations.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.model.domain.ServeItem;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.service.IServeService;
import com.jzo2o.mysql.utils.PageHelperUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务表 服务实现类
 * </p>
 *
 * @author lxr
 * @since 2025-09-15
 */
@Service
public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements IServeService {
    @Resource
    ServeItemMapper serveItemMapper;
    @Resource
    RegionMapper regionMapper;
    /**
     * 区域服务分页查询
     *
     * @param servePageQueryReqDTO 查询条件
     * @return 分页结果
     */
    @Override
    public PageResult<ServeResDTO> page(ServePageQueryReqDTO servePageQueryReqDTO) {
        return PageHelperUtils.selectPage(servePageQueryReqDTO,
                () -> baseMapper.queryList(servePageQueryReqDTO.getRegionId()));

    }

    /**
     * 区域服务项删除
     *
     * @param id 服务项id
     */
    @Override
    public void deleteById(Long id) {
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("服务项不存在");
        }
        //启用状态
        Integer saleStatus = serve.getSaleStatus();

        //1.删除校验：只有草稿状态方可删除
        if (!(FoundationStatusEnum.INIT.getStatus() == saleStatus)) {
            throw new ForbiddenOperationException("只有草稿状态方可删除");
        }

        //2.根据id删除
        baseMapper.deleteById(id);
    }
    /**
     * 服务项下架
     *
     * @param id 服务项id
     */
    @Override
    public void offSale(Long id) {
        //查询服务项
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("服务项不存在");
        }
        //启用状态
        Integer saleStatus = serve.getSaleStatus();
        //启用状态方可禁用
        if (!(FoundationStatusEnum.ONSALE.getStatus() == saleStatus)) {
            throw new ForbiddenOperationException("上架状态方可下架");
        }

        //更新禁用状态
        LambdaUpdateWrapper<Serve> updateWrapper = Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getSaleStatus, FoundationStatusEnum.OFFSALE.getStatus());
        update(updateWrapper);
    }
    /**
     * 服务项上架
     *
     * @param id 服务项id
     */
    @Override
    public void onSale(Long id) {
        //查询服务项
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("服务项不存在");
        }

        Integer saleStatus = serve.getSaleStatus();
        //区域服务下架或者草稿状态才可以上架
        if (!(FoundationStatusEnum.OFFSALE.getStatus() == saleStatus||FoundationStatusEnum.INIT.getStatus()==saleStatus)) {
            throw new ForbiddenOperationException("下架状态方可上架");
        }
        //服务项的启用状态
        ServeItem serveItem = serveItemMapper.selectById(serve.getServeItemId());
        if (ObjectUtil.isNull(serveItem)||FoundationStatusEnum.ENABLE.getStatus()!=serveItem.getActiveStatus()) {
            throw new ForbiddenOperationException("服务项不存在或未启用");
        }
        //更新禁用状态
        LambdaUpdateWrapper<Serve> updateWrapper = Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getSaleStatus, FoundationStatusEnum.ONSALE.getStatus());
        update(updateWrapper);
    }
    /**
     * 设置热门
     *
     * @param id 服务项id
     */
    @Override
    public void onHot(Long id) {
        //查询服务项
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("服务项不存在");
        }
        //启用状态
        Integer isHot = serve.getIsHot();
        //启用状态方可禁用
        if (!(FoundationStatusEnum.OFFHOT.getStatus() == isHot)) {
            throw new ForbiddenOperationException("非热门状态方可设置热门");
        }

        //更新禁用状态
        LambdaUpdateWrapper<Serve> updateWrapper = Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getIsHot, FoundationStatusEnum.ONHOT.getStatus());
        update(updateWrapper);
    }
    /**
     * 取消热门
     *
     * @param id 服务项id
     */
    @Override

    public void offHot(Long id) {

        //查询服务项
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("服务项不存在");
        }
        //启用状态
        Integer isHot = serve.getIsHot();
        //启用状态方可禁用
        if (!(FoundationStatusEnum.ONHOT.getStatus() == isHot)) {
            throw new ForbiddenOperationException("热门状态方可取消热门");
        }

        //更新禁用状态
        LambdaUpdateWrapper<Serve> updateWrapper = Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getIsHot, FoundationStatusEnum.OFFHOT.getStatus());
        update(updateWrapper);
    }
    /**
     * 区域服务批量增加
     *
     * @param id 服务项id
     */
    @Override
    @Transactional(rollbackFor =Exception.class)
    public void batchAdd(List<ServeUpsertReqDTO> serveUpsertReqDTOS) {
        List<Serve> serveList = new ArrayList<>(serveUpsertReqDTOS.size());
        for (ServeUpsertReqDTO serveUpsertReqDTO : serveUpsertReqDTOS) {

            //1.判断服务项存在缺失启用状态
            Long serveItemId = serveUpsertReqDTO.getServeItemId();
            ServeItem serveItem = serveItemMapper.selectById(serveItemId);
            if (ObjectUtil.isNull(serveItem) || FoundationStatusEnum.ENABLE.getStatus() != serveItem.getActiveStatus()) {
                throw new ForbiddenOperationException("服务项不存在或未启用");
            }
            //2.判断当前服务项在当前区域是否已经存在
            Long regionId = serveUpsertReqDTO.getRegionId();
            Long count = lambdaQuery().eq(Serve::getServeItemId, serveItemId)
                    .eq(Serve::getRegionId, regionId)
                    .count();
            if (count > 0) {
                throw new ForbiddenOperationException("当前服务项目已存在");
            }
            Region region = regionMapper.selectById(regionId);
            if (ObjectUtil.isNull(region)) {
                throw new ForbiddenOperationException("当前区域存在");
            }
            Serve serve = BeanUtil.toBean(serveUpsertReqDTO, Serve.class);
            serve.setCityCode(region.getCityCode());
            serveList.add(serve);
        }
        this.saveBatch(serveList);



    }
    /**
     * 区域服务价格修改
     *
     * @param id 服务项id
     */
    @Override
    public void update(Long id, BigDecimal price) {
        //1.更新服务价格
        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getPrice, price)
                .update();
        if(!update){
            throw new CommonException("修改服务价格失败");
        }
         baseMapper.selectById(id);
    }
    /**
     * 根据区域id和售卖状态查询关联服务数量
     *
     * @param regionId   区域id
     * @param saleStatus 售卖状态，0：草稿，1下架，2上架。可传null，即查询所有状态
     *
     */
    @Override
    public long querySaleServeCountByServeId(Long regionId, int saleStatus) {
        LambdaQueryWrapper<Serve> queryWrapper = Wrappers.<Serve>lambdaQuery()
                .eq(Serve::getRegionId, regionId)
                .eq(ObjectUtil.isNotEmpty(saleStatus),Serve::getSaleStatus, saleStatus);
        return baseMapper.selectCount(queryWrapper);
    }

    @Override
    public long queryServeCountByServeItemIdAndSaleStatus(Long serveItemId, Integer saleStatus) {
        LambdaQueryWrapper<Serve> queryWrapper = Wrappers.<Serve>lambdaQuery()
                .eq(Serve::getServeItemId, serveItemId)
                .eq(ObjectUtil.isNotEmpty(saleStatus), Serve::getSaleStatus, saleStatus);
        return baseMapper.selectCount(queryWrapper);
    }


}

